package Simulator;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Random;
import java.util.Vector;


/**
 * Class Quota
 * Classe de generation des demandes d'ascenseur qui respect des quotas
 */
public class Quota {

    /**
     * Vector de quotaZone pour assigner un quota à chaque zone
     */
    private Vector<QuotaZone> qz;
    /**
     * Constructeur
     */
    public Quota () {
        this.qz = new Vector<QuotaZone>();
    };

    /**
     * Methode qui supprime toutes les zones
     */
    public void clear(){
	    this.qz.clear();
    }
    
    /**
     * Methode qui ajoute une zone
     * @param startHour heure de debut de la zone
     * @param endHour heure de fin de la zone
     * @param startWeekDay jour de debut de la zone
     * @param endWeekDay jour de fin de la zone
     * @param dailyRequestNumber Nombre de requete par jour
     * @param startCallerZone etage de debut de la zone d'appel
     * @param endCallerZone etage de fin de la zone d'appel
     * @param startTargetZone etage de debut de la zone de destination
     * @param endTargetZone etage de fin de la zone de destination
     * @param s Simulateur
     */
    public void addZone(int startHour, int endHour, int startWeekDay, int endWeekDay, int dailyRequestNumber, int startCallerZone, int endCallerZone,  int startTargetZone, int endTargetZone, Simulator s){
	    QuotaZone z = new QuotaZone(s);
	    z.setDailyRequestNumber(dailyRequestNumber);
	    z.setDailySendedRequestNumber(0);

	    z.setStartCallerZone(startCallerZone);
	    z.setEndCallerZone(endCallerZone);

	    z.setStartHour(startHour);
	    z.setEndHour(endHour);

	    z.setStartTargetZone(
		    startTargetZone);
	    z.setEndTargetZone(endTargetZone);

	    z.setStartWeekDay(startWeekDay);
	    z.setEndWeekDay(endWeekDay);

	    this.qz.add(z);
    }


    /**
     * Donne n demande a générer dans l'heure
     * @param	currentDate Date de la demande
     */
    public void getRequests(Date currentDate) {
	    Calendar cal = GregorianCalendar.getInstance();
	    cal.setTime(currentDate);
	    int hour = cal.get(Calendar.HOUR_OF_DAY);
	    int weekday = cal.get(Calendar.DAY_OF_WEEK);
	    Iterator it = this.qz.iterator();
	    QuotaZone q;
	    Random randGenerator = new Random();
	    int nbRequests,i;
	    //On parcourt toutes les zones
	    while(it.hasNext()){
		    q = (QuotaZone)it.next();
		    //Pour les zones qui nous interesse
		    if(
				(
					(
						q.getStartWeekDay() <= q.getEndWeekDay() &&
						weekday>= q.getStartWeekDay() &&
						weekday <= q.getEndWeekDay()
					) ||
					(
						q.getStartWeekDay() > q.getEndWeekDay() &&
						(
							weekday >= q.getStartWeekDay() ||
							weekday <= q.getEndWeekDay()
						)
					)
				) &&
				(
					(
						q.getStartHour() <= q.getEndHour() &&
						hour >= q.getStartHour() &&
						hour <= q.getEndHour()
					) ||
					(
						q.getStartHour() > q.getEndHour() &&
						(
							hour >= q.getStartHour() ||
							hour <= q.getStartHour()
						)
					)
				)
			){
			    if(q.getDailyRequestNumber() > q.getDailySendedRequestNumber()){
				    //Generation du nombre de requete
				    if(q.getEndHour() == hour){
					    //Si on est a la dernier heure de la zone on genere toutes les requete restante
					    nbRequests = q.getDailyRequestNumber()-q.getDailySendedRequestNumber();
				    }
				    else{
					    //Cas d'une plage normal
					    if(q.getEndHour() >= q.getStartHour()){
						nbRequests = (q.getDailyRequestNumber()) / (q.getStartHour()-q.getEndHour());
					    }
					    //Cas d'une plage a cheval avec minuit
					    else{
						    nbRequests = (q.getDailyRequestNumber()) / ((24-q.getStartHour())+(q.getEndHour()));
					    }
				    }
				    //Generation des requests
				    for(i=0;i<nbRequests;i++){
					    q.sendRequest(currentDate);
				    }
			    }
		    }
		    else{
			    q.init();
		    }
	    }
    }


}